<?php

// Comma Separated Value (CSV) File Format 
class Ext_Utils_CSV
{
    
    const DS_ROWSET = 1;
    const DS_ARRAY = 2;
    const DS_STATEMENT = 3;

    private $dataSource = null;

    private $dataSourceType = null;

    private $isFirstLine = true;

    private $title = null;

    private $separator = ',';

    public function Ext_Utils_CSV( $ds, $title = null )
    {
        
        // guardamos el titulo
        $this->title = $title;
        
        // Rowset
        if ( $ds instanceof Zend_Db_Table_Rowset ) {
            $this->dataSource = $ds;
            $this->dataSourceType = self::DS_ROWSET;
            return;
        }
        
        // Array
        if ( is_array( $ds ) ) {
            $this->dataSource = $ds;
            $this->dataSourceType = self::DS_ARRAY;
            reset( $this->dataSource );
            return;
        }
        
        // Statement
        if ( $ds instanceof Zend_Db_Statement ) {
            $this->dataSource = $ds;
            $this->dataSourceType = self::DS_STATEMENT;
            return;
        }
    
    }

    public function setSeparator( $newSeparator )
    {
        $this->separator = $newSeparator;
    }

    public function getNextLine()
    {
        
        if ( $this->isFirstLine && $this->title !== null && is_array( $this->title ) ) {
            $this->isFirstLine = false;
            return $this->returnHeader();
        }
        
        $row = null;
        switch( $this->dataSourceType ) {
            case self::DS_ARRAY:
                $row = current( $this->dataSource );
                next( $this->dataSource );
                break;
            case self::DS_STATEMENT:
                $row = $this->dataSource->fetch( Zend_Db::FETCH_ASSOC );
                break;
            case self::DS_ROWSET:
                $row = $this->dataSource->current();
                $this->dataSource->next();
                break;
        }
        
        // si no hay mas datos devolvemos null
        if ( $row == null )
            return null;
            
        // si hay data generamos una linea de CSV
        return $this->convertRowToCSV( $row );
    }

    private function convertRowToCSV( $r )
    {
        
        $data = array();
        
        if ( $this->title === null ) {
            
            foreach ( $r as $k => $v ) {
                $data[] = $this->encodeData( $v );
            }
        
        } else {
            
            foreach ( $r as $k => $v ) {
                if ( isset( $this->title[ $k ] ) ) {
                    $data[] = $this->encodeData( $v );
                }
            }
        
        }
        
        $line = implode( $this->separator, $data );
        return $line . "\n";
    }

    private function returnHeader()
    {
        $data = array();
        foreach ( $this->title as $column => $colDesc ) {
            $data[] = $this->encodeData( $colDesc );
        }
        return implode( $this->separator, $data ) . "\n";
    }

    public function getAll()
    {
        $ret = "";
        while( $line = $this->getNextLine() ) {
            $ret .= $line;
        }
        return $ret;
    }

    // Aca convierto a iso latin 1 para el excel de windows.
    protected function encodeData( $utf8String )
    {
        $v = Ext_Utils_Charset::encodeToLatin1($utf8String);
        $v = str_replace( "\"", "\"\"", $v );
        $v = '"' .  $v . '"';
        return $v;
    }

}
